<!-- 修改手机号弹窗 -->
<script lang="tsx">
import { defineComponent, ref, computed, reactive, watch } from 'vue';
import { $t } from '@vben/locales';
import { ElMessage } from 'element-plus';
import Code from '#/components/common/code.vue';
import { getVoiceVerificationCodeApi, getVerificationCodeApi } from '#/api/core/auth';
import { verifyUserPhoneApi, updateUserPhoneApi } from '#/api/system/user';
import { TelMatcher } from '#/utils/constants';
import { useCodeName } from '#/hooks/useCodeName';
import SliderDialog from "#/components/slider-dialog.vue"
import { getVoiceVerificationOpenCodeApi, getVerificationOpenCodeApi } from "#/api/core/auth"

export default defineComponent({
  name: 'ChangePhoneDialog',
  props: {
    modelValue: {
      type: Boolean,
      default: false,
    },
    currentPhone: {
      type: String,
      default: '',
    },
  },
  emits: ['update:modelValue', 'confirm'],
  setup(props, { emit }) {
    const oldPhoneFormRef = ref();
    const newPhoneFormRef = ref();
    const loading = ref(false);
    const sliderDialogVisible = ref(false)
    const sliderDialogRef = ref<any>(null)
    let codeCallBack: Function | null = null;
    // 控制两个对话框的显示状态
    const showOldPhoneDialog = ref(false);
    const showNewPhoneDialog = ref(false);

    // 语音验证码相关
    const { isVoiceCode, codeBtnName, codeInputPlaceholder } = useCodeName();
    const oldPhoneCodeRef = ref<any>(null);
    const newPhoneCodeRef = ref<any>(null);

    // 表单数据
    const oldPhoneForm = reactive({
      oldPhoneCode: '' // 旧手机号验证码
    });

    const newPhoneForm = reactive({
      newPhone: '', // 新手机号
      newPhoneCode: '', // 新手机号验证码
    });

    // 旧手机号表单验证规则
    const oldPhoneRules = computed(() => ({
      oldPhoneCode: [
        { required: true, message: codeInputPlaceholder.value, trigger: 'blur' }
      ]
    }));

    // 新手机号表单验证规则
    const newPhoneRules = computed(() => ({
      newPhone: [
        {
          required: true,
          validator: (_rule: any, value: string, callback: any) => {
            if (!value) {
              callback(new Error($t('common.phonePhTxt')));
            } else if (!TelMatcher.test(value)) {
              callback(new Error($t('common.phonePhTxt')));
            } else if (value === props.currentPhone) {
              callback(new Error($t('personal.phoneSameError')));
            } else {
              callback();
            }
          },
          trigger: 'blur'
        }
      ],
      newPhoneCode: [
        { required: true, message: codeInputPlaceholder.value, trigger: 'blur' }
      ],
    }));

    // 获取旧手机号验证码
    const getOldPhoneCode = async (callback: Function) => {
      // 直接发送验证码
      codeCallBack = callback;
      sliderDialogVisible.value = true
      // if (isVoiceCode.value) {
      //   getVoiceVerificationCodeApi({ phoneNumber: props.currentPhone });
      // } else {
      //   getVerificationCodeApi({ phoneNumber: props.currentPhone });
      // }
    };

    // 获取新手机号验证码
    const getNewPhoneCode = async (callback: Function) => {
      // 验证新手机号
      newPhoneFormRef.value?.validateField('newPhone', (valid: boolean) => {
        console.log(valid, 'valid');
        if (valid) {
          // 验证成功（无错误信息）
          codeCallBack = callback;
          sliderDialogVisible.value = true
        }
      });
    };

    // 切换语音验证码 - 旧手机号对话框
    const getOldPhoneVoiceCode = (value: boolean, event?: Event) => {
      if (oldPhoneCodeRef.value?.isCounting) return;
      if (event) {
        event.preventDefault();
        event.stopPropagation();
      }
      isVoiceCode.value = value;
      oldPhoneForm.oldPhoneCode = '';
      oldPhoneFormRef.value?.clearValidate(['oldPhoneCode']);
    };

    // 切换语音验证码 - 新手机号对话框
    const getNewPhoneVoiceCode = (value: boolean, event?: Event) => {
      if (newPhoneCodeRef.value?.isCounting) return;
      if (event) {
        event.preventDefault();
        event.stopPropagation();
      }
      isVoiceCode.value = value;
      newPhoneForm.newPhoneCode = '';
      newPhoneFormRef.value?.clearValidate(['newPhoneCode']);
    };

    // 重置Code组件倒计时的辅助方法
    const resetOldPhoneCodeCountdown = () => {
      oldPhoneCodeRef.value?.resetCountdown();
    };

    // 关闭所有弹窗
    const handleClose = () => {
      showOldPhoneDialog.value = false;
      showNewPhoneDialog.value = false;
      // 重置表单和状态
      oldPhoneForm.oldPhoneCode = '';
      newPhoneForm.newPhone = '';
      newPhoneForm.newPhoneCode = '';
      oldPhoneFormRef.value?.resetFields();
      newPhoneFormRef.value?.resetFields();
      isVoiceCode.value = false;
      emit('update:modelValue', false);
    };

    // 关闭旧手机号对话框
    const handleOldPhoneClose = () => {
      showOldPhoneDialog.value = false;
      emit('update:modelValue', false);
      oldPhoneForm.oldPhoneCode = '';
      oldPhoneFormRef.value?.resetFields();
      isVoiceCode.value = false;
    };

    // 验证旧手机号 - 第一步
    const verifyOldPhone = async () => {
      try {
        loading.value = true;
        oldPhoneFormRef.value?.validate(async (valid: boolean) => {
          if (valid) {
            // 调用验证旧手机号API
            const data = {
              phone: props.currentPhone,
              verificationCode: oldPhoneForm.oldPhoneCode,
            };

            await verifyUserPhoneApi(data);

            ElMessage.success($t('personal.oldPhoneVerifiedSuccess'));

            // 关闭旧手机号对话框，打开新手机号对话框
            showOldPhoneDialog.value = false;
            showNewPhoneDialog.value = true;

            // 重置验证码倒计时
            resetOldPhoneCodeCountdown();

            // 重置语音验证码状态
            isVoiceCode.value = false;
          }
        });
      } catch (error: any) {
      } finally {
        loading.value = false;
      }
    };

    // 确认修改手机号 - 第二步
    const confirmNewPhone = async () => {
      try {
        loading.value = true;

        // 验证表单字段
        await new Promise((resolve, reject) => {
          newPhoneFormRef.value?.validate((valid: boolean) => {
            if (valid) {
              resolve(true);
            } else {
              reject(new Error('validation failed'));
            }
          });
        });

        // 调用修改手机号API
        const data = {
          phone: newPhoneForm.newPhone,
          verificationCode: newPhoneForm.newPhoneCode,
        };

        console.log(data, 'data');

        await updateUserPhoneApi(data);

        ElMessage.success($t('personal.phoneChangedSuccess'));
        emit('confirm', { newPhone: data.phone });
        handleClose();

      } catch (error: any) {
      } finally {
        loading.value = false;
      }
    };

    // 旧手机号对话框提交按钮状态
    const isOldPhoneSubmitDisabled = computed(() => {
      return !oldPhoneForm.oldPhoneCode.trim();
    });

    // 新手机号对话框提交按钮状态
    const isNewPhoneSubmitDisabled = computed(() => {
      return !newPhoneForm.newPhone.trim() || !newPhoneForm.newPhoneCode.trim();
    });

    watch(() => props.modelValue, (val) => {
      if (val) {
        showOldPhoneDialog.value = true;
        showNewPhoneDialog.value = false;
      }
    });
    const phone = computed(() => {
      if (showOldPhoneDialog.value) {
        return props.currentPhone
      } else {
        return newPhoneForm.newPhone
      }
    })

    const handleVerifySuccess = async (data: string) => {
      try { 
        codeCallBack?.();
        if (isVoiceCode.value) {
          await getVoiceVerificationOpenCodeApi({ phoneNumber: phone.value, captchaKey: data })
        } else {
          await getVerificationOpenCodeApi({ phoneNumber: phone.value, captchaKey: data })
        }
      } catch (error) {
        console.error('验证失败:', error);
      }
    }


    return () => (
      <>
        {/* 验证旧手机号对话框 */}
        <el-dialog
          v-model={showOldPhoneDialog.value}
          title={$t('personal.verifyOldPhone')}
          width="450px"
          onClose={handleOldPhoneClose}
          append-to-body
          destroy-on-close
          close-on-click-modal={false}
          class="change-phone-dialog"
          v-slots={{
            footer: () => (
              <div class="flex justify-end">
                <el-button onClick={handleOldPhoneClose}>{$t('common.cancel')}</el-button>
                <el-button
                  type="primary"
                  onClick={verifyOldPhone}
                  disabled={isOldPhoneSubmitDisabled.value}
                  loading={loading.value}
                >
                  {$t('common.confirm')}
                </el-button>
              </div>
            )
          }}
        >
          <div>
            <div class="text-right text-sm mb-[10px] text-[#595959]">
              {$t('personal.verifyOldPhoneTip')}
            </div>

            <el-form
              ref={oldPhoneFormRef}
              model={oldPhoneForm}
              rules={oldPhoneRules.value}
              label-width="80px"
              label-position="right"
            >
              <el-form-item label={$t('personal.originalPhone')}>
                <el-input
                  value={props.currentPhone}
                  disabled
                  class="disabled-input"
                  maxlength={11}
                />
              </el-form-item>

              <el-form-item label={$t('personal.verificationCode')} prop="oldPhoneCode">
                <el-input
                  v-model={oldPhoneForm.oldPhoneCode}
                  placeholder={codeInputPlaceholder.value}
                  maxlength={isVoiceCode.value ? 10 : 6}
                  minlength={3}
                  v-slots={{
                    append: () => (
                      <Code
                        ref={oldPhoneCodeRef}
                        onGetCode={getOldPhoneCode}
                        authCode={props.currentPhone}
                        codeName={codeBtnName.value}
                      />
                    )
                  }}
                />
              </el-form-item>
            </el-form>

            <p class="text-[12px] text-[#909399] h-[20px] w-full text-right">
              {!isVoiceCode.value ? (
                <>
                  {$t('login.noSmsCode')}
                  <span
                    class="text-[#0067D1] cursor-pointer ml-1"
                    onClick={(event) => getOldPhoneVoiceCode(true, event)}
                  >
                    {$t('login.voiceLogin')}
                  </span>
                </>
              ) : (
                <span
                  class="text-[#0067D1] cursor-pointer"
                  onClick={(event) => getOldPhoneVoiceCode(false, event)}
                >
                  {$t('login.switchSmsCode')}
                </span>
              )}
            </p>
          </div>
        </el-dialog>

        {/* 绑定新手机号对话框 */}
        <el-dialog
          v-model={showNewPhoneDialog.value}
          title={$t('personal.changePhone')}
          width="450px"
          onClose={handleClose}
          append-to-body
          destroy-on-close
          close-on-click-modal={false}
          class="change-phone-dialog"
          v-slots={{
            footer: () => (
              <div class="flex justify-end">
                <el-button onClick={handleClose}>{$t('common.cancel')}</el-button>
                <el-button
                  type="primary"
                  onClick={confirmNewPhone}
                  disabled={isNewPhoneSubmitDisabled.value}
                  loading={loading.value}
                >
                  {$t('common.confirm')}
                </el-button>
              </div>
            )
          }}
        >
          <div>
            <div class="text-right text-sm mb-[10px] text-[#595959]">
              {$t('personal.phoneSecurityTip')}
            </div>

            <el-form
              ref={newPhoneFormRef}
              model={newPhoneForm}
              rules={newPhoneRules.value}
              label-width="80px"
              label-position="right"
            >
              <el-form-item label={$t('personal.newPhone')} prop="newPhone">
                <el-input
                  v-model={newPhoneForm.newPhone}
                  placeholder={$t('personal.pleaseEnterNewPhone')}
                  maxlength={11}
                  clearable
                />
              </el-form-item>

              <el-form-item label={$t('personal.verificationCode')} prop="newPhoneCode">
                <el-input
                  v-model={newPhoneForm.newPhoneCode}
                  placeholder={codeInputPlaceholder.value}
                  maxlength={isVoiceCode.value ? 10 : 6}
                  minlength={3}
                  v-slots={{
                    append: () => (
                      <Code
                        ref={newPhoneCodeRef}
                        onGetCode={getNewPhoneCode}
                        authCode={newPhoneForm.newPhone}
                        codeName={codeBtnName.value}
                      />
                    )
                  }}
                />
              </el-form-item>
            </el-form>

            <p class="text-[12px] text-[#909399] h-[20px] w-full text-right">
              {!isVoiceCode.value ? (
                <>
                  {$t('login.noSmsCode')}
                  <span
                    class="text-[#0067D1] cursor-pointer ml-1"
                    onClick={(event) => getNewPhoneVoiceCode(true, event)}
                  >
                    {$t('login.voiceLogin')}
                  </span>
                </>
              ) : (
                <span
                  class="text-[#0067D1] cursor-pointer"
                  onClick={(event) => getNewPhoneVoiceCode(false, event)}
                >
                  {$t('login.switchSmsCode')}
                </span>
              )}
            </p>
          </div>
        </el-dialog>
        <SliderDialog v-model:visible={sliderDialogVisible.value} ref={sliderDialogRef} phone={phone.value} onVerifySuccess={handleVerifySuccess} />
      </>
    );
  },
});
</script>

<style>
.change-phone-dialog :deep(.el-form-item .el-form-item__label) {
  @apply pb-2 font-medium;
}

.change-phone-dialog :deep(.el-form-item .el-form-item__content) {
  @apply flex-1;
}

.change-phone-dialog :deep(.disabled-input .el-input__inner) {
  background-color: #f5f7fa;
  color: #909399;
}

/* 确保输入框组合样式一致 */
.change-phone-dialog :deep(.el-input-group__append) {
  border: 1px solid var(--el-input-border-color);
  border-left: 0;
}
</style>
